package design_pattern.FutureMode;

import java.util.function.Consumer;

/**
 * @Author: 蔡翔
 * @Date: 2019/11/6 14:04
 * @Version 1.0
 *
 * 其实这个future的原理就是，把run方法 提交给这个FutureService，它new 出一个线程帮你监听 任务有没有完成。
 */
public class FutureService {
    //<T>Future<T> 代表返回值是 Future
    //注意 这里submit 提交的是一个接口函数，当你在外部调用的时候 这个函数需要你重写 FutureTask这个接口里面的方法的。
    public <T>Future<T> submit(final FutureTask<T> task){
        //主要的工作在FutureTask里面。FutureTask完成以后再放到Future里面取。
        // 外部需要拿结果 我就把Future给他。
        AsyncFuture<T> asyncFuture = new AsyncFuture<>();
        new Thread(()->{
            //这里的call 就是调用 外部重写了的FutureTask里面的call 方法。
            T result = task.call();
            asyncFuture.done(result);
        }).start();

        //这里返回给外部的就是Future<String> future ,

        return asyncFuture;
    }

    //回调通知 方法 (生产好的结果数据（是一块蛋糕），所以要一个消费者去消费它),,Consumer<T>这个T 表示的是入参，输入的
    public <T>Future<T> submit(final FutureTask<T> task, final Consumer<T> consumer){

        //主要的工作在FutureTask里面。FutureTask完成以后再放到Future里面取。
        // 外部需要拿结果 我就把Future给他。
        AsyncFuture<T> asyncFuture = new AsyncFuture<>();
        new Thread(()->{
            //这里的call 就是调用 外部重写了的FutureTask里面的call 方法。
            T result = task.call();
            asyncFuture.done(result);
            //把消息交给消费者，让消费者自己处理，因为加入了消费者，可以返回Future<T>也可以没有返回值
            // 1.通过Future的形式，外部去get；2.也可以 我这边好了去通知外部，也就是我这里调用外部实现的方法。
            consumer.accept(result);
            // 这里的accept 才是真正的调用了 回调函数，写在sumbit里面的只是对 Consumer 接口 的一个实现。
        }).start();

        //这里返回给外部的就是Future<String> future ,
        return asyncFuture;
    }
}
